<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);

// 定义安装程序根目录
define('INSTALL_ROOT', dirname(__FILE__));
// 定义应用根目录
define('APP_ROOT', realpath(INSTALL_ROOT . '/../../'));

require_once 'model.php';

// 添加会话支持
session_start();

$action = $_GET['action'] ?? 'index';
$install = new InstallModel();
$step = 1;
$template = '';

// 添加调试输出

switch ($action) {
    case 'env-check':
        $step = 2;
        $systemInfo = $install->systemList();
        $dirPermission = $install->checkDirPermission();
        $template = 'template/env-check.php';
        break;
        
    case 'db-config':
        $step = 3;
        $template = 'template/db-config.php';
        break;
        
    case 'execute':
        $step = 4;
        $template = 'template/execute.php';
        break;
        
    case 'complete':
        $step = 5;
        $template = 'template/complete.php';
        break;
        
    case 'test-db':
        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            $config = $_POST;
            $result = $install->testDatabase($config);
            header('Content-Type: application/json');
            echo json_encode($result);
            exit;
        }
        break;
        
    case 'execute-step':
        header('Content-Type: text/event-stream');
        header('Cache-Control: no-cache');
        header('X-Accel-Buffering: no');

        if (ob_get_level()) ob_end_clean();
        
        try {
            $dbConfig = isset($_GET['config']) ? json_decode(urldecode($_GET['config']), true) : null;
            
            if (!$dbConfig) {
                throw new Exception('未找到数据库配置信息');
            }

            // 定义命令队列
            $commands = [
                [
                    'name' => '准备安装环境',
                    'type' => 'output',
                    'action' => function() {
                        sendMessage('output', '正在准备安装环境...');
                        return true;
                    }
                ],
                [
                    'name' => '验证数据库连接',
                    'type' => 'database',
                    'action' => function() use ($install, $dbConfig) {
                        sendMessage('detail', '正在验证数据库连接...');
                        $result = $install->testDatabase($dbConfig);
                        if(!$result['status']){
                            throw new Exception('数据库连接失败：' . $result['message']);
                        }
                        sendMessage('success', '数据库连接成功');
                        return true;
                    }
                ],
                [
                    'name' => '检查数据库状态',
                    'type' => 'database',
                    'action' => function() use ($install, $dbConfig) {
                        sendMessage('detail', '正在验证数据库是否为空...');
                        $result = $install->checkDatabaseEmpty($dbConfig);
                        if($result){
                            sendMessage('success', '数据库不为空');
                            $clearResult = $install->clearDatabase($dbConfig);
                            if(!$clearResult['status']){
                                throw new Exception('清空数据库失败：' . $clearResult['message']);
                            }
                            sendMessage('success', '数据库清空成功');
                        }else{
                            sendMessage('success', '数据库为空，可直接安装');
                        }
                        return true;
                    }
                ],
                [
                    'name' => '写入配置文件',
                    'type' => 'file',
                    'action' => function() use ($dbConfig) {
                        $envPath = __DIR__ . '/../../.env';
                        sendMessage('output', '检查配置文件...');
                        
                        $envContent = <<<EOT
APP_DEBUG = true

DB_TYPE = mysql
DB_HOST = {$dbConfig['db_host']}
DB_NAME = {$dbConfig['db_name']}
DB_USER = {$dbConfig['db_user']}
DB_PASS = {$dbConfig['db_password']}
DB_PORT = {$dbConfig['db_port']}
DB_CHARSET = utf8
DB_PREFIX   = {$dbConfig['db_prefix']}

DEFAULT_LANG = zh-cn
EOT;

                        sendMessage('output', '正在写入配置文件...');
                        if (file_put_contents($envPath, $envContent) === false) {
                            throw new Exception('写入配置文件失败');
                        }

                        // 修改文件权限为755
                        if (!chmod($envPath, 0755)) {
                            throw new Exception('修改文件权限失败');
                        }

                        // 尝试修改文件用户组为www（需要适当的系统权限）
                        if (function_exists('posix_getgrnam')) {
                            $groupInfo = posix_getgrnam('www');
                            if ($groupInfo && !chgrp($envPath, $groupInfo['gid'])) {
                                sendMessage('warning', '无法修改文件用户组为www，请手动设置');
                            }
                        }

                        sendMessage('success', '配置文件写入成功');
                        return true;
                    }
                ],
                [
                    'name' => '检查并安装依赖',
                    'type' => 'composer',
                    'action' => function() use ($install) {
                        sendMessage('output', '开始检查 Composer 依赖...');

                        // 获取项目根目录
                        $rootPath = dirname(dirname(__DIR__));

                        // 检查 vendor 目录是否存在
                        if (is_dir($rootPath . '/vendor') && file_exists($rootPath . '/vendor/autoload.php')) {
                            sendMessage('detail', '检测到已安装依赖');

                            // 检查 composer.lock 文件
                            if (file_exists($rootPath . '/composer.lock')) {
                                sendMessage('detail', '验证依赖完整性...');

                                // 执行 composer validate
                                $validateCommand = 'composer validate';
                                $process = proc_open($validateCommand, [
                                    0 => ["pipe", "r"],
                                    1 => ["pipe", "w"],
                                    2 => ["pipe", "w"]
                                ], $pipes, $rootPath);

                                if (is_resource($process)) {
                                    fclose($pipes[0]);
                                    $output = stream_get_contents($pipes[1]);
                                    $error = stream_get_contents($pipes[2]);
                                    fclose($pipes[1]);
                                    fclose($pipes[2]);
                                    $return_value = proc_close($process);

                                    if ($return_value === 0) {
                                        sendMessage('success', '依赖完整性验证通过');
                                        return true;
                                    }
                                }
                            }
                        }

                        sendMessage('detail', '正在安装依赖...');

                        // 设置描述符
                        $descriptorspec = array(
                            0 => array("pipe", "r"),
                            1 => array("pipe", "w"),
                            2 => array("pipe", "w")
                        );

                        // 构建安装命令
                        $command = 'composer install --no-interaction';

                        // 打开进程
                        $process = proc_open($command, $descriptorspec, $pipes, $rootPath);

                        if (is_resource($process)) {
                            // 关闭标准输入
                            fclose($pipes[0]);

                            // 设置非阻塞模式
                            stream_set_blocking($pipes[1], 0);
                            stream_set_blocking($pipes[2], 0);

                            // 持续读取输出直到进程结束
                            while (true) {
                                $status = proc_get_status($process);

                                // 读取标准输出
                                $stdout = stream_get_contents($pipes[1]);
                                if ($stdout) {
                                    sendMessage('detail', trim($stdout));
                                }

                                // 读取错误输出
                                $stderr = stream_get_contents($pipes[2]);
                                if ($stderr) {
                                    sendMessage('error', trim($stderr));
                                }

                                // 如果进程已结束，退出循环
                                if (!$status['running']) {
                                    break;
                                }

                                usleep(100000);
                            }

                            // 关闭管道
                            fclose($pipes[1]);
                            fclose($pipes[2]);

                            // 获取进程退出码
                            $return_value = proc_close($process);

                            if ($return_value === 0) {
                                sendMessage('success', 'Composer 依赖安装完成');
                                return true;
                            } else {
                                throw new Exception('Composer 依赖安装失败');
                            }
                        } else {
                            throw new Exception('无法启动 Composer 安装进程');
                        }
                    }
                ],
                [
                    'name' => '安装数据库',
                    'type' => 'database',
                    'action' => function() use ($install, $dbConfig) {
                        sendMessage('output', '开始执行数据库安装...');
                        
                        // 获取项目根目录
                        $rootPath = dirname(dirname(__DIR__));
                        
                        // 执行数据库迁移
                        try {
                            $output = [];
                            $returnVar = 0;
                            $command = 'cd ' . escapeshellarg($rootPath) . ' && php think migrate:run --app=adminapi';
                            
                            // 记录开始时间
                            $startTime = microtime(true);
                            sendMessage('detail', '开始执行数据库安装...');
                            sendMessage('detail', '执行命令: ' . $command);
                            
                            // 执行命令
                            exec($command . ' 2>&1', $output, $returnVar);
                            
                            // 记录执行时间
                            $endTime = microtime(true);
                            $executionTime = round($endTime - $startTime, 2);
                            
                            // 输出执行结果
                            foreach ($output as $line) {
                                sendMessage('detail', trim($line));
                            }
                            
                            if ($returnVar !== 0) {
                                throw new Exception("数据库迁移失败，返回代码: {$returnVar}");
                            }
                            
                            sendMessage('success', '数据库安装完成，用时：' . $executionTime . '秒');
                            return true;
                            
                        } catch (Exception $e) {
                            sendMessage('error', '安装过程出现错误：' . $e->getMessage());
                            sendMessage('error', '请检查错误日志或手动执行命令：' . $command);
                            throw $e;
                        }
                    }
                ],
                //  [
                //      'name' => '前端环境安装',
                //      'type' => 'frontend',
                //      'action' => function() {
                //          sendMessage('output', '开始检查前端环境...');
                        
                //          // 获取项目根目录和前端目录
                //          $rootPath = dirname(dirname(__DIR__));
                //          $frontendPath = $rootPath . '/template/admin';
                        
                //          try {
                //              // 检查前端目录是否存在
                //              if (!is_dir($frontendPath)) {
                //                  throw new Exception('前端目录不存在：' . $frontendPath);
                //              }
                            
                //              // 检查 Node.js 是否安装
                //              sendMessage('detail', '检查 Node.js 环境...');
                //              $nodeVersion = trim(shell_exec('node -v'));
                //              if (empty($nodeVersion)) {
                //                  throw new Exception('未检测到 Node.js，请先安装 Node.js');
                //              }
                //              sendMessage('success', 'Node.js 版本: ' . $nodeVersion);
                            
                //              // 检查 npm 是否安装
                //              sendMessage('detail', '检查 npm 环境...');
                //              $npmVersion = trim(shell_exec('npm -v'));
                //              if (empty($npmVersion)) {
                //                  throw new Exception('未检测到 npm，请先安装 npm');
                //              }
                //              sendMessage('success', 'npm 版本: ' . $npmVersion);
                            
                //              // 检查是否已经安装过依赖
                //              if (is_dir($frontendPath . '/node_modules') && file_exists($frontendPath . '/package-lock.json')) {
                //                  sendMessage('detail', '检测到已存在的依赖...');
                //              } else {
                //                  // 设置npm注册表为淘宝镜像
                //                  sendMessage('detail', '配置npm镜像源...');
                //                  $setRegistryCmd = 'npm config set registry https://registry.npmmirror.com';
                //                  exec($setRegistryCmd, $output, $returnVar);
                //                  if ($returnVar !== 0) {
                //                      sendMessage('warning', '设置npm镜像源失败，将使用默认源');
                //                  } else {
                //                      sendMessage('success', '已设置npm镜像源为淘宝镜像');
                //                  }
                                
                //                  // 执行 npm install
                //                  sendMessage('detail', '开始安装前端依赖...');
                //                  $descriptorspec = [
                //                      0 => ["pipe", "r"],
                //                      1 => ["pipe", "w"],
                //                      2 => ["pipe", "w"]
                //                  ];
                                
                //                  // 在前端目录中执行命令，添加--legacy-peer-deps参数解决依赖兼容性问题
                //                  $process = proc_open('npm install --legacy-peer-deps --no-fund --no-audit', $descriptorspec, $pipes, $frontendPath);
                                
                //                  if (is_resource($process)) {
                //                      // 设置非阻塞模式
                //                      stream_set_blocking($pipes[1], 0);
                //                      stream_set_blocking($pipes[2], 0);
                                    
                //                      // 持续读取输出直到进程结束
                //                      while (true) {
                //                          $status = proc_get_status($process);
                                        
                //                          // 读取标准输出
                //                          $stdout = stream_get_contents($pipes[1]);
                //                          if ($stdout) {
                //                              sendMessage('detail', trim($stdout));
                //                          }
                                        
                //                          // 读取错误输出
                //                          $stderr = stream_get_contents($pipes[2]);
                //                          if ($stderr) {
                //                              sendMessage('error', trim($stderr));
                //                          }
                                        
                //                          // 如果进程已结束，退出循环
                //                          if (!$status['running']) {
                //                              break;
                //                          }
                                        
                //                          usleep(100000);
                //                      }
                                    
                //                      // 关闭管道
                //                      fclose($pipes[0]);
                //                      fclose($pipes[1]);
                //                      fclose($pipes[2]);
                                    
                //                      $return_value = proc_close($process);
                //                      if ($return_value !== 0) {
                //                          throw new Exception('前端依赖安装失败，请检查网络或手动安装');
                //                      }
                                    
                //                      sendMessage('success', '前端依赖安装完成');
                //                  }
                //              }
                            
                //              // 执行 npm run build
                //              sendMessage('detail', '开始构建前端资源...');
                //              $process = proc_open('npm run build', $descriptorspec, $pipes, $frontendPath);
                            
                //              if (is_resource($process)) {
                //                  // 设置非阻塞模式
                //                  stream_set_blocking($pipes[1], 0);
                //                  stream_set_blocking($pipes[2], 0);
                                
                //                  // 持续读取输出直到进程结束
                //                  while (true) {
                //                      $status = proc_get_status($process);
                                    
                //                      // 读取标准输出
                //                      $stdout = stream_get_contents($pipes[1]);
                //                      if ($stdout) {
                //                          sendMessage('detail', trim($stdout));
                //                      }
                                    
                //                      // 读取错误输出
                //                      $stderr = stream_get_contents($pipes[2]);
                //                      if ($stderr) {
                //                          sendMessage('error', trim($stderr));
                //                      }
                                    
                //                      // 如果进程已结束，退出循环
                //                      if (!$status['running']) {
                //                          break;
                //                      }
                                    
                //                      usleep(100000);
                //                  }
                                
                //                  // 关闭管道
                //                  fclose($pipes[0]);
                //                  fclose($pipes[1]);
                //                  fclose($pipes[2]);
                                
                //                  $return_value = proc_close($process);
                //                  if ($return_value !== 0) {
                //                      throw new Exception('前端资源构建失败，请检查构建日志或手动执行 npm run build 命令');
                //                  }
                                
                //                  sendMessage('success', '前端资源构建完成');
                //              }
                            
                //              return true;
                            
                //          } catch (Exception $e) {
                //              sendMessage('error', '前端环境配置失败: ' . $e->getMessage());
                //              throw $e;
                //          }
                //      }
                //  ],
                [
                    "name" => "最后初始化",
                    "type" => "output",
                    "action" => function() use ($install) {
                        sendMessage('output', '开始初始化...');
                        
                        // 获取 public 目录路径
                        $publicPath = dirname(dirname(__DIR__)) . '/public';
                        $lockFile = $publicPath . '/install.lock';
                        
                        try {
                            // 创建锁文件
                            $content = date('Y-m-d H:i:s');
                            if (file_put_contents($lockFile, $content) === false) {
                                throw new Exception('无法创建安装锁定文件');
                            }
                            
                            // 验证文件是否创建成功
                            if (!file_exists($lockFile)) {
                                throw new Exception('安装锁定文件创建失败');
                            }
                            
                            sendMessage('success', '安装锁定文件创建成功');
                            return true;
                            
                        } catch (Exception $e) {
                            sendMessage('error', '初始化失败: ' . $e->getMessage());
                            throw $e;
                        }
                    }
                ]
            ];

            // 执行命令队列
            $totalSteps = count($commands);
            foreach($commands as $index => $command) {
                try {
                    sendMessage('step', "执行步骤 " . ($index + 1) . "/{$totalSteps}: {$command['name']}", 
                        ($index + 1) * (100 / $totalSteps));
                    $command['action']();
                } catch (Exception $e) {
                    sendMessage('error', "执行 {$command['name']} 失败: " . $e->getMessage());
                    throw $e;
                }
            }

            sendMessage('complete', '安装完成！');

        } catch (Exception $e) {
            sendMessage('error', '安装失败：' . $e->getMessage());
        }

        sendMessage('close');
        exit;
        break;
        
    default:
        $step = 1;
        $template = 'template/index.php';
        break;
}


// 检查模板文件是否存在
if (!file_exists($template)) {
    die('模板文件不存在：' . $template);
}

// 加载主模板
include 'template/main.php';

// 添加一个辅助函数来发送消息
function sendMessage($type, $content = '', $progress = 0) {
    echo "data: " . json_encode([
        'type' => $type,
        'content' => $content,
        'progress' => $progress
    ]) . "\n\n";
    ob_flush();
    flush();
    usleep(100000); // 添加小延迟使输出更平滑
}